package com.forum.core.util;

import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public class ClassUtil {
	private static final Logger logger = Logger.getLogger(ClassUtil.class);
	private static Method getterMethod(Class theClass, String propertyName) {

		Method[] methods = theClass.getDeclaredMethods();
		for (int i=0; i<methods.length; i++) {
			// only carry on if the method has no parameters
			if ( methods[i].getParameterTypes().length == 0 ) {
				String methodName = methods[i].getName();

				// try "get"
				if ( methodName.startsWith("get") ) {
					String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
					String testOldMethod = methodName.substring(3);
					if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
						return methods[i];
					}

				}

				// if not "get", then try "is"
				if ( methodName.startsWith("is") ) {
					String testStdMethod = Introspector.decapitalize( methodName.substring(2) );
					String testOldMethod = methodName.substring(2);
					if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
						return methods[i];
					}
				}
			}
		}
		return null;
	}
	private static Method setterMethod(Class theClass, String propertyName) {

		Method[] methods = theClass.getDeclaredMethods();
		Method potentialSetter = null;
		for (int i=0; i<methods.length; i++) {
			String methodName = methods[i].getName();

			if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) {
				String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
				String testOldMethod = methodName.substring(3);
				if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
					return methods[i];
				}
			}
		}
		return potentialSetter;
	}
	
	public static Object getFieldValue(Object target,String propertyName,Object... args){
		
		try {
			if (args!=null&&args.length==0) {
				args = null;
			}
			Method getter = getterMethod(target.getClass(), propertyName);
			if (getter!=null) {
				return getter.invoke(target, args);
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	
	public static List getFields(Class clazz){
		List<String> fields = new ArrayList<String>(0);
		getAllFields(fields, clazz);
		return fields;
	}
	
	private static void getAllFields(List<String> fields,Class clazz){
		if (clazz==null) {
			return ;
		}
		Class parent = clazz.getSuperclass();
		if (parent!=null) {
			getAllFields(fields, parent);
		}
		Field[] fs=clazz.getDeclaredFields();
		if (fs!=null) {
			for (Field field : fs) {
				fields.add(field.getName());
			}
		}
	}
	
	public static Class createClass(String clazz){
		try {
			return Class.forName(clazz);
		} catch (ClassNotFoundException e) {
			logger.error(clazz+"找不到！");
		}
		return null;
		
	}
	
	public static Field getField(Class clazz,String name){
		try {
			if (clazz==null) {
				return null;
			}
			Field filed = clazz.getDeclaredField(name);
			if (filed==null) {
				return getField(clazz.getSuperclass(), name);
			}
			return filed;
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		}
		return null;
	}
}
